package models

import (
	"time"

	"gitee.com/lzqysoft/ga_wz_backend/libs/encrypt"

	"github.com/astaxie/beego/orm"
)

// 事务相关操作

// Up2Outbound 根据出库单更新出库单状态，库存，并初始化实施实例Implement和实施详情ImplementDetail
func Up2Outbound(soutId string, user *User) error {
	o := orm.NewOrm()
	err := o.Begin()
	// 获取出库单详情
	outs, err := GetOutStatus2BySinId(soutId)
	if err != nil {
		o.Rollback()
		return err
	}
	// 修改库存
	err = RemoveStockBySins(outs)
	if err != nil {
		o.Rollback()
		return err
	}
	// 更新出库单状态
	err = UpdateSout2Finish(soutId, user)
	if err != nil {
		o.Rollback()
		return err
	}
	sout, err := GetSoutById(soutId)
	if err != nil {
		o.Rollback()
		return err
	}
	order, err := GetOrderById(sout.OrderId)
	if err != nil {
		o.Rollback()
		return err
	}
	prodId := make([]string, 0)
	for _, v := range outs {
		prodId = append(prodId, v.ProdId)
	}
	plan := 0
	for _, v := range outs {
		plan += v.Count
	}
	impl, err := AddImplementsFromOrderAndSoutAndOuts(order, sout, user, plan)
	if err != nil {
		o.Rollback()
		return err
	}
	prods, err := GetProdInIds(&prodId)
	if err != nil {
		o.Rollback()
		return err
	}
	_, err = AddImplementFromImplementAndProdsAndUserAndOuts(order, impl, *prods, user, outs)
	if err != nil {
		o.Rollback()
		return err
	}
	err = o.Commit()
	return err
}

// InstallSync 确认安装后调用的方法，如果安装成功，则生成服务实例, 如果已经为安装状态，则只修改安装信息
func InstallSync(item *ImplementDetail, user *User) (err error) {
	o := orm.NewOrm()
	if err != nil {
		o.Rollback()
		return err
	}
	err = o.Begin()

	// 首先查询是否已存在服务实例
	serv2, err := GetServByImplementDetailId(item.Id)

	// 没有这条记录
	if err != nil {
		if err == orm.ErrNoRows {
			// 没有这条记录
			err = UpdateImplementDetail(item)
			if err != nil {
				o.Rollback()
				return err
			}

			order, err := GetOrderById(item.OrderId)
			if err != nil {
				o.Rollback()
				return err
			}

			prod, err := GetProdById(item.ProdId)
			if err != nil {
				o.Rollback()
				return err
			}
			cust, err := GetCustById(order.CustId)
			if err != nil {
				o.Rollback()
				return err
			}
			serv := &Serv{}
			serv.Id = encrypt.GetGuid()
			serv.Prod = prod
			serv.Order = order
			serv.OrderName = order.Name
			serv.Name = item.Alisa
			serv.Cust = cust
			serv.Macid = item.PUID
			serv.Model = prod.Model
			serv.Spec = prod.Spec
			serv.Price = prod.Price
			serv.Address = item.Address
			serv.Account = item.Account
			serv.Contact = item.Contact
			serv.Phone = item.Phone
			serv.Remark = item.InstallRemark
			serv.ImplementDetailId = item.Id
			serv.Creater, serv.Updater, serv.Ctime, serv.Utime, serv.Isdelete, serv.Status =
				order.Creater, user.Abbr, time.Now(), time.Now(), 0, 1

			// 添加服务实例
			_, err = AddServ(serv)
			if err != nil {
				o.Rollback()
				return err
			}
			// 更新安装实例
			cnt, err := o.QueryTable(new(ImplementDetail)).Filter("ImplementId", item.ImplementId).Filter("InstallResult", 2).Count()
			if err != nil {
				o.Rollback()
				return err
			}
			total, err := o.QueryTable(new(ImplementDetail)).Filter("ImplementId", item.ImplementId).Count()
			if err != nil {
				o.Rollback()
				return err
			}
			imp, err := GetImplementById(item.ImplementId)
			if err != nil {
				o.Rollback()
				return err
			}
			imp.Really = int(cnt)
			if cnt != 0 && cnt > 0 && cnt != total {
				imp.InstallType = 1 // 部分安装
			} else if cnt == 0 && total > 0 {
				imp.InstallType = 0 // 未安装
			} else if cnt == total && total > 0 {
				imp.InstallType = 2 // 全部安装
			}
			err = UpdateImplementById(imp)
			if err != nil {
				o.Rollback()
				return err
			}
		} else {
			// 数据异常，回滚
			o.Rollback()
			return err
		}
	} else {
		// 存在记录,修改相关信息
		err = UpdateImplementDetail(item)
		if err != nil {
			o.Rollback()
			return err
		}
		serv2.Contact = item.Contact
		serv2.Phone = item.Phone
		serv2.Address = item.Address
		serv2.Remark = item.InstallRemark
		serv2.Updater, serv2.Utime = user.Abbr, time.Now()
		err = UpdateServById(serv2)
		if err != nil {
			o.Rollback()
			return err
		}
	}


	err = o.Commit()
	return err
}
